package com.xbongbong.saas.analytical.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.FormDataValidateDataHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.help.team.TeamUserHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.domain.entity.LabelEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ContactErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CustomerErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.team.TeamAfterVerifyDTO;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.analytical.SaasValidateAnalyticalService;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CustomerStageEntity;
import com.xbongbong.saas.domain.entity.PublicGroupSeniorEntity;
import com.xbongbong.saas.domain.entity.ext.ClueEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.enums.LinkAddOperationFlagEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.help.SaasDataInitHelp;
import com.xbongbong.saas.help.SaveFormatHelp;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerStageModel;
import com.xbongbong.saas.model.FundSetModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.LabelModel;
import com.xbongbong.saas.model.PublicGroupSeniorModel;
import com.xbongbong.saas.service.toolbox.help.FundSetHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.apache.commons.collections4.MapUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @author 吴峰
 * @date 2021/07/15 14:28
 */
@Service("customerAnalyticalServiceImpl")
public class CustomerValidateAnalyticalServiceImpl implements SaasValidateAnalyticalService {
    private static final Logger LOG = LoggerFactory.getLogger(CustomerValidateAnalyticalServiceImpl.class);


    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private ClueModel clueModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private FormDataValidateDataHelp formDataValidateDataHelp;
    @Resource
    private LabelModel labelModel;
    @Resource
    private FundSetModel fundSetModel;
    @Resource
    private FundSetHelp fundSetHelp;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private TeamUserHelp teamUserHelp;
    @Resource
    private PublicGroupSeniorModel publicGroupSeniorModel;
    @Resource
    private CustomerStageModel customerStageModel;

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
    }

    @Override
    public void analyticalData(ValidateDataDTO validateDataDTO) throws XbbException {
        beforeSave(validateDataDTO);
        if (CollectionsUtil.isNotEmpty(validateDataDTO.getOwnerIds()) || CollectionsUtil.isNotEmpty(validateDataDTO.getCoUserId()) || Objects.equals(validateDataDTO.getIsImport(), BasicConstant.ONE) || (!Objects.equals(validateDataDTO.getSubBusinessType(), XbbRefTypeEnum.CUSTOMER_PUBLIC.getCode()) && !Objects.equals(validateDataDTO.getFromOuterLink(), 1))) {
            // 外链不校验团队，因为外链不支持人员处理
            teamUserHelp.beforeVerifyUserTeam(validateDataDTO);
        }
    }

    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        JSONObject data = validateDataDTO.getData();
        String corpid = validateDataDTO.getCorpid();
        Long dataId = validateDataDTO.getDataId();
        Long formId = validateDataDTO.getFormId();
        String name = FastJsonHelper.getStringFromFormData(data, CustomerManagementEnum.NAME.getAttr());
        if (Objects.nonNull(data.get(CustomerManagementEnum.BIRTHDAY.getAttr()))) {
            // 为了兼容审批将生日字段设置为不可见时，validateDataDTO的explainMap会将生日字段过滤掉，
            // 所以只能重新查询一次，才能判断text_21字段的类型是否为生日字段（企业客户没有生日字段），才能继续进行下面的生日的解析
            PaasFormExplainEntity customerExplain = paasFormExplainModel.getByFormId(validateDataDTO.getFormId(), corpid);
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(customerExplain.getExplains(), CustomerManagementEnum.BIRTHDAY.getAttr());
            if (FieldTypeEnum.BIRTHDAY.getType().equals(explainMap.getOrDefault(CustomerManagementEnum.BIRTHDAY.getAttr(), new FieldAttrEntity()).getFieldType())) {
                SaveFormatHelp.formatBirthday4Save(data, CustomerManagementEnum.BIRTHDAY.getAttr(), CustomerManagementEnum.BIRTHDAY_FLAG.getAttr(), CustomerManagementEnum.BIRTHDAY_MMDD.getAttr());
            }
        }
        SaveFormatHelp.formatLinkBusiness4Save(data, CustomerManagementEnum.PARENT.getAttr(), CustomerManagementEnum.PARENT_HIDE.getAttr(), CustomerManagementEnum.PARENT.getFieldType());
        SaveFormatHelp.formatLinkBusiness4Save(data, CustomerManagementEnum.CLUE_ID.getAttr(), CustomerManagementEnum.CLUE_NAME_ID.getAttr(), CustomerManagementEnum.CLUE_ID.getFieldType());
        String creatorId = FastJsonHelper.getStringFromFormData(data, CustomerManagementEnum.CREATOR.getAttr());
        if (StringUtil.isEmpty(creatorId)) {
            data.put(CustomerManagementEnum.CREATOR.getAttr(), validateDataDTO.getUserId());
        }
        data.put(CustomerManagementEnum.IS_PUBLIC.getAttr(), 0);
        if (Objects.isNull(validateDataDTO.getOwnerIds()) || (Objects.nonNull(validateDataDTO.getOwnerIds()) && validateDataDTO.getOwnerIds().isEmpty())) {
            data.put(CustomerManagementEnum.IS_PUBLIC.getAttr(),1);
        } else {
            // 新建有负责人设置其分配时间
            if (dataId == null) {
                data.put(CustomerManagementEnum.DISTRIBUTION_DATE.getAttr(), DateTimeUtil.getInt());
            }
        }
        if (dataId != null && Objects.equals(validateDataDTO.getIsImport(), 1)) {
            // 客户阶段不允许编辑
            CustomerEntityExt customerEntityExt = customerModel.getByKey(dataId, corpid);
            if (Objects.isNull(customerEntityExt)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            String oldStageCode = FastJsonHelper.getStringOrDefaultFromFormData(customerEntityExt.getData(), CustomerManagementEnum.CUSTOMER_STAGE.getAttr(),  "");
            String oldWastage = FastJsonHelper.getStringOrDefaultFromFormData(customerEntityExt.getData(), CustomerManagementEnum.WASTAGE.getAttr(), "");
            data.put(CustomerManagementEnum.CUSTOMER_STAGE.getAttr(), oldStageCode);
            data.put(CustomerManagementEnum.WASTAGE.getAttr(), oldWastage);
        }

        if (Objects.nonNull(dataId) && dataId !=0) {
            //所属分组不允许编辑.不允许覆盖导入
            CustomerEntityExt customerEntityExt = customerModel.getByKey(dataId, corpid);
            String oldPublicGroup = FastJsonHelper.getStringOrDefaultFromFormData(customerEntityExt.getData(), CustomerManagementEnum.PUBLIC_GROUP.getAttr(),  "");
            data.put(CustomerManagementEnum.PUBLIC_GROUP.getAttr(), oldPublicGroup);
            Object oldBackNum = customerEntityExt.getData().get(CustomerManagementEnum.BACK_NUM.getAttr());
            if (Objects.isNull(oldBackNum)) {
                data.remove(CustomerManagementEnum.BACK_NUM.getAttr());
            } else {
                data.put(CustomerManagementEnum.BACK_NUM.getAttr(), oldBackNum);
            }
        }

        if (Objects.isNull(dataId)) {
            if (Objects.equals(validateDataDTO.getIsImport(), 1)) {
                //新建导入所属分组
                String newPublicGroup = FastJsonHelper.getStringOrDefaultFromFormData(data, CustomerManagementEnum.PUBLIC_GROUP.getAttr(),  "");
                if (StringUtil.isNotEmpty(newPublicGroup)) {
                    List<PublicGroupSeniorEntity> groupNameList = publicGroupSeniorModel.getByGroupName(newPublicGroup, formId, corpid,BasicConstant.ONE);
                    if (CollectionsUtil.isNotEmpty(groupNameList)) {
                        PublicGroupSeniorEntity publicGroupSeniorEntity = groupNameList.get(0);
                        if (!Objects.equals(publicGroupSeniorEntity.getGroupType(),BasicConstant.TWO)) {
                            data.put(CustomerManagementEnum.PUBLIC_GROUP.getAttr(), publicGroupSeniorEntity.getId());
                        } else {
                            //无分组 直接不用绑定
                            data.remove(CustomerManagementEnum.PUBLIC_GROUP.getAttr());
                        }
                    } else {
                        data.remove(CustomerManagementEnum.PUBLIC_GROUP.getAttr());
                    }
                }

            } else {
                //其他新建这里直接移除掉该字段
                data.remove(CustomerManagementEnum.PUBLIC_GROUP.getAttr());
            }
            //退回次数不支持任何场景的新建
            data.remove(CustomerManagementEnum.BACK_NUM.getAttr());
        }


        if (Objects.nonNull(validateDataDTO.getClueId())) {
            // 从线索转换过来
            Long clueId = validateDataDTO.getClueId();
            ClueEntityExt entityExt = clueModel.getByKey(clueId, corpid);
            if (Objects.nonNull(entityExt)) {
                String clueName = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
                JSONArray idArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, CustomerManagementEnum.CLUE_ID.getAttr(), new JSONArray());
                if(CollectionsUtil.isNotEmpty(idArr)) {
                    boolean hasThisClue = false;
                    for (Object o : idArr) {
                        if (Objects.equals(clueId.toString(), o.toString())) {
                            hasThisClue = true;
                        }
                    }
                    if (!hasThisClue) {
                        idArr.add(clueId.toString());
                        JSONArray clueNames = data.getJSONArray(CustomerManagementEnum.CLUE_NAME_ID.getAttr());
                        clueNames.add(clueName);
                    }
                } else {
                    data.put(CustomerManagementEnum.CLUE_ID.getAttr(), Arrays.asList(clueId.toString()));
                    data.put(CustomerManagementEnum.CLUE_NAME_ID.getAttr(), Arrays.asList(clueName));
                }
            }
        }
        // 校验上级客户
        verifyParentCustomer(data, corpid, dataId);

        // 处理客户阶段关联客户状态
        handleCustomerStageLinkCustomerType(data, corpid, dataId, validateDataDTO.getFormId());

        // 关联新建
        JSONArray contactArray = FastJsonHelper.getJsonArrFromFormData(data, CustomerManagementEnum.ADD_CONTACT.getAttr());
        if (contactArray != null) {
            // 校验联系人
            verifyContact(corpid, contactArray, dataId, name, validateDataDTO);
        }
        data.put(CustomerManagementEnum.ADD_CONTACT.getAttr(), contactArray);
        for (Map.Entry<String,Object> entry : SaasDataInitHelp.initCustomer().entrySet()){
            SaasDataInitHelp.antDataSet(data,entry.getKey(),entry.getValue());
        }
        //这里还需要处理导入的应收账期，如果isImport为1就是导入，导入默认去获取默认账期
        if (Objects.equals(validateDataDTO.getIsImport(), 1)) {
            String period = fundSetHelp.getImportDefaultPeriod(corpid, formId, data);
            data.put(CustomerManagementEnum.RECEIVABLE_PERIOD.getAttr(), period);
            validateDataDTO.setData(data);
        } else {
            //处理应收账期字段,应收账期字段保存成json字符串
            JSONObject jsonObject = FastJsonHelper.getJsonObjectOrDefaultFromFormData(data, CustomerManagementEnum.RECEIVABLE_PERIOD.getAttr(), null);
            //合同订单，非手动创建应收的模式下，应收账期为空，并且应收账期不可见，设置默认值
            //当jsonObject为空时，代表应收账期字段是不可见的
            boolean flag = Objects.equals(validateDataDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            if (Objects.isNull(jsonObject) && flag){
                //获得当前数据创建的模式
                Long nowModelType = fundSetModel.getModelType(corpid,XbbRefTypeEnum.CRM);
                boolean periodFlag = !Objects.equals(ModelTypeEnum.PLAN.getCode(), nowModelType);
                if (periodFlag){
                    //获取关联的默认账期
                    String linkPeriodValue = fundSetHelp.getDefaultFormatPeriod(corpid, formId, data);
                    //获得关联应收帐期得attr
                    if (Objects.nonNull(linkPeriodValue)){
                        data.put(CustomerManagementEnum.RECEIVABLE_PERIOD.getAttr(), linkPeriodValue);
                    }
                }
            }else{
                String receivablePeriodStr = Objects.isNull(jsonObject) ? null : JSON.toJSONString(jsonObject);
                data.put(CustomerManagementEnum.RECEIVABLE_PERIOD.getAttr(), receivablePeriodStr);
            }
            validateDataDTO.setData(data);
        }
    }

    /**
     * 校验上级客户
     *
     * @param data
     * @param corpid
     * @param dataId
     * @throws
     * @author long.rao
     * @date 2020-06-10 19:03
     */
    public void verifyParentCustomer(JSONObject data, String corpid, Long dataId) throws XbbException {
        Long parentId = FastJsonHelper.getLongOrDefaultFromFormData(data, CustomerManagementEnum.PARENT.getAttr(), 0L);
        if (parentId <= 0) {
            return;
        }
        if (dataId != null && dataId > 0) {
            if (Objects.equals(dataId, parentId)) {
                throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201022);
            }
            IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
            boolQueryBuilder.filter(termQuery(CustomerManagementEnum.getEsAttr4Keyword(CustomerManagementEnum.PARENT), dataId));
            boolQueryBuilder.filter(termQuery(FieldTypeEnum.DATAID.getAlias(), parentId));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(boolQueryBuilder);
            SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
            searchRequest.source(sourceBuilder);
            CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
            countRequest.query(searchRequest.source().query());
            Long count = xbbElasticsearchRestTemplate.count(countRequest);
            if (count !=null && count > 0L) {
                throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201023);
            }
        }
    }

    /**
     * 客户里关联新建联系人校验联系人
     *
     * @param corpid       公司id
     * @param contactArray 联系人数据
     * @param dataId       客户id
     * @param name         客户名称
     * @author feng.zheng
     * @date 2019/2/21 20:42
     */
    private void verifyContact(String corpid, JSONArray contactArray, Long dataId, String name, ValidateDataDTO validateDataDTO) throws XbbException {
        JSONArray linkCustomerArray = new JSONArray();
        JSONObject linkCustomerObj = new JSONObject();
        linkCustomerObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, dataId);
        linkCustomerObj.put(StringConstant.SAAS_LINK_BUSINESS_NAME, name);
        linkCustomerArray.add(linkCustomerObj);
        // 获取联系人的解释和必要信息
        PaasFormExplainEntity contactFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.CONTACT.getCode(), corpid);
        Map<String, FieldAttrEntity> contactExplainMap = ExplainUtil.getExplainMap(contactFormExplainEntity.getExplains(), "");

        // fix: 19222 【客户管理】关联新建联系人，设置联系人名称不允许有重复值，但是新增的时候仍然能保存成功。
        // 不允许姓名重复时才做处理
        Integer noRepeat = contactExplainMap.get(ContactEnum.NAME.getAttr()).getNoRepeat();
        if (Objects.nonNull(noRepeat) && Objects.equals(1, noRepeat)){
            Set<String> contactNameSet = new HashSet<>();
            JSONArray contactAddArray = new JSONArray();
            contactArray.forEach(obj -> {
                JSONObject contactObj = (JSONObject) obj;
                // 排除删除联系人的情况，只做新增联系人时排重
                Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
                if (!Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())) {
                    JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
                    contactNameSet.add(contactData.getString(ContactEnum.NAME.getAttr()));
                    contactAddArray.add(contactObj);
                }
            });
            if (contactNameSet.size() < contactAddArray.size()){
                throw new XbbException(CustomerErrorCodeEnum.API_ERROR_201033);
            }
        }
        // 生日
        contactArray.forEach(obj -> {
            JSONObject contactObj = (JSONObject) obj;
            JSONObject data = contactObj.getJSONObject(StringConstant.JSON_DATA);
            try {
                SaveFormatHelp.formatBirthday4Save(data, ContactEnum.BIRTHDAY.getAttr(), ContactEnum.BIRTHDAY_FLAG.getAttr(), ContactEnum.BIRTHDAY_MMDD.getAttr());
            } catch (XbbException e) {

            }
        });
        // 若开启电话判重，进行处理
        FieldAttrEntity phoneAttrEntity = contactExplainMap.get(ContactEnum.PHONE.getAttr());
        Integer phoneRepeatFlag = phoneAttrEntity.getSubForm().getItems().get(1).getNoRepeat();
        String titleName = phoneAttrEntity.getAttrName();
        if (Objects.equals(phoneRepeatFlag, 1)) {
            HashSet<String> phoneNumSet = new HashSet<>();
            for (Object obj : contactArray) {
                JSONObject contactObj = (JSONObject) obj;
                Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
                // 排除删除联系人的情况，只做新增联系人时排重
                if (Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())) {
                    break;
                }
                JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
                JSONArray PhoneFormArr = contactData.getJSONArray(ContactEnum.PHONE.getAttr());
                if (CollectionsUtil.isEmpty(PhoneFormArr)) {
                    continue;
                }
                for (Object PhoneForm : PhoneFormArr) {
                    JSONObject phoneForm = (JSONObject) PhoneForm;
                    String contactPhone = phoneForm.getString("text_2");
                    if (phoneNumSet.contains(contactPhone)) {
                        if(contactPhone==null){
                            contactPhone = "";
                        }
                        throw new XbbException(ContactErrorCodeEnum.API_ERROR_204010, ContactErrorCodeEnum.API_ERROR_204010.getMsg(), titleName, contactPhone);
                    }
                    phoneNumSet.add(contactPhone);
                }
            }
        }

        // 联系人公共部分属性
        ValidateDataDTO contactValidateDataDTO = new ValidateDataDTO();
        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
        saasNeedRedundantAttrPojo.setIsRelationItem(1);
        BeanUtil.copyProperties(validateDataDTO, contactValidateDataDTO);
        BeanUtil.copyProperties(contactFormExplainEntity, contactValidateDataDTO);
        contactValidateDataDTO.setCreatorId(Objects.isNull(validateDataDTO.getCreatorId()) ? validateDataDTO.getUserId() : validateDataDTO.getCreatorId());
        contactValidateDataDTO.setExplainMap(contactExplainMap);
        // 每个联系人的data和dataId赋值
        List<ValidateDataDTO> needAddValidateDataDTO = new ArrayList<>();
        List<ValidateDataDTO> needDelValidateDataDTO = new ArrayList<>();
        List<ValidateDataDTO> needUpdateValidateDataDTO = new ArrayList<>();
        List<String> contactPhoneList = new ArrayList<>();
        JSONArray newContactArr = new JSONArray();
        List<String> noRepeatAttr = new ArrayList<>();
        String labelAttr = null;
        Iterator<Map.Entry<String, FieldAttrEntity>> iterator = contactExplainMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, FieldAttrEntity> entry = iterator.next();
            if (Objects.equals(entry.getValue().getNoRepeat(), 1)) {
                noRepeatAttr.add(entry.getKey());
            }
            if (Objects.equals(entry.getValue().getFieldType(), FieldTypeEnum.LABEL.getType())) {
                labelAttr = entry.getValue().getAttr();
            }
        }
        Map<String, Long> delPhoneMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,  Map<String, Long>> noRepeatMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        int contactNum = contactArray.size();
        // 联系人数据id集合,电话判重用
        Set<Long> contactDataIdSet = new HashSet<>();
        Map<String, Long> labelPojoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (StringUtil.isNotEmpty(labelAttr)) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("formId", contactFormExplainEntity.getFormId());
            param.put("corpid", contactFormExplainEntity.getCorpid());
            param.put("appId", contactFormExplainEntity.getAppId());
            param.put("del", DelEnum.NORMAL.getDel());
            List<LabelEntity> entitys = labelModel.findEntitys(param);
            entitys.forEach(item->{
                labelPojoMap.put(item.getName(), item.getId());
            });
        }
        for (Object obj : contactArray) {
            // 单个联系人数据
            JSONObject contactObj = (JSONObject) obj;
            // 表示编辑时数据是否被更改，被更改operationFlag为1,被删除operationFlag为2
            Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
            // 联系人的data数据
            JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
            Long contactDataId = contactObj.getLong(StringConstant.DATA_ID);
            if (Objects.nonNull(contactDataId)) {
                contactDataIdSet.add(contactDataId);
            }
//            if (StringUtil.isNotEmpty(labelAttr)) {
//                String string = contactData.getString(labelAttr);
//                if ( Objects.nonNull(string) ) {
//                    String[] split = string.split(",");
//                    JSONArray jsonArray = new JSONArray();
//                    for (String s : split) {
//                        if (Objects.nonNull(labelPojoMap.get(s))){
//                            jsonArray.add(labelPojoMap.get(s));
//                        }
//                    }
//                    contactData.put(labelAttr, jsonArray);
//                }
//            }
            if (Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode()) && Objects.nonNull(contactDataId)) {
                contactNum--;
                List<String> phoneListFromFormData = FastJsonHelper.getPhoneListFromFormData(contactData, ContactEnum.PHONE.getAttr());
                for (String phone : phoneListFromFormData) {
                    delPhoneMap.put(phone, contactDataId);
                }
                for (String attr : noRepeatAttr) {
                    Map<String, Long> noRepeatDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    if (noRepeatMap.containsKey(attr)) {
                        noRepeatDataMap = noRepeatMap.get(attr);
                    }
                    noRepeatDataMap.put(contactData.getString(attr), contactDataId);
                    noRepeatMap.put(attr, noRepeatDataMap);
                }
            }
        }
        // 只有一个联系人时，设置该联系人为主联系人
        if (1 == contactNum) {
            JSONObject contactObj = (JSONObject) contactArray.get(0);
            JSONObject data = contactObj.getJSONObject(StringConstant.JSON_DATA);
            data.put(ContactEnum.IS_MAIN.getAttr(), BasicConstant.ONE);
        }
        for (Object obj : contactArray) {
            // 单个联系人数据
            JSONObject contactObj = (JSONObject) obj;
            // 表示编辑时数据是否被更改，被更改operationFlag为1,被删除operationFlag为2
            Integer operationFlag = contactObj.getInteger(StringConstant.OPERATION_FLAG);
            // 联系人的data数据
            JSONObject contactData = contactObj.getJSONObject(StringConstant.JSON_DATA);
            JSONArray originalOwnerJsonArray = contactData.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
            if (Objects.isNull(originalOwnerJsonArray)) {
                String ownerId = contactObj.getString(FieldTypeEnum.OWNERID.getAlias());
                if (StringUtil.isNotEmpty(ownerId)) {
                    originalOwnerJsonArray = new JSONArray();
                    ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = new ReturnUserAndDepartmentPojo();
                    returnUserAndDepartmentPojo.setId(ownerId);
                    originalOwnerJsonArray.add(returnUserAndDepartmentPojo);
                }
            }
            JSONArray originalCouserJsonArray = contactData.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
            Long contactDataId = contactObj.getLong(StringConstant.DATA_ID);
            contactValidateDataDTO.setDataId(contactDataId);
            contactValidateDataDTO.setSerialNo(contactObj.getString(FieldTypeEnum.SERIALNO.getAlias()));
            contactValidateDataDTO.setImportDelContact(null);

            // 去掉传来的关联客户属性来兼容新建 提前为了让审批数据格式一致
            contactData.remove(ContactEnum.CUSTOMER_NAME.getAttr());
            contactData.remove(ContactEnum.CUSTOMER_NAME_LINK_TEXT.getAttr());
            contactData.put(ContactEnum.CUSTOMER_NAME.getAttr(), linkCustomerArray);
            contactValidateDataDTO.setData(contactData);
            saasNeedRedundantAttrPojo.setContactPhoneList(contactPhoneList);
            contactValidateDataDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
            ProSaveHelp.analyticalData(contactValidateDataDTO);
            if (Objects.nonNull(contactValidateDataDTO.getDepartmentId())) {
                // 这里重新放下否则在客户和联系人联系人审批时会缺少所属部门信息
                contactValidateDataDTO.getData().put(FieldTypeEnum.DEPARTMENTID.getAlias(), contactValidateDataDTO.getDepartmentId());
                contactObj.put(FieldTypeEnum.DEPARTMENTID.getAlias(), contactValidateDataDTO.getDepartmentId());
            }
            List<String> phoneListFromFormData = FastJsonHelper.getPhoneListFromFormData(contactData, ContactEnum.PHONE.getAttr());
            if (Objects.isNull(contactDataId)) {
                for (String phone : phoneListFromFormData) {
                    if (delPhoneMap.containsKey(phone)) {
                        contactValidateDataDTO.setDataId(delPhoneMap.get(phone));
                        contactValidateDataDTO.setImportDelContact(1);
                    }
                }
                for (String attr : noRepeatAttr) {
                    if (MapUtils.isNotEmpty(noRepeatMap) &&  noRepeatMap.containsKey(attr)
                            && noRepeatMap.get(attr).containsKey(contactData.getString(attr))) {
                        contactValidateDataDTO.setDataId(noRepeatMap.get(attr).get(contactData.getString(attr)));
                        contactValidateDataDTO.setImportDelContact(1);
                    }
                }
            }
            try {
                // fix: 26324 【成功部】字段填写完整报错报错提示“联系人类型没有填写”
                //  如果联系人已经删除 就跳过此校验
                if (!Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())){
                    contactValidateDataDTO.setContactDataIdSet(contactDataIdSet);
                    formDataValidateDataHelp.validateData(contactValidateDataDTO);
                    //新增、编辑的时候需要校验一下团队
                    contactData.put(FieldTypeEnum.OWNERID.getAlias(), originalOwnerJsonArray);
                    contactData.put(FieldTypeEnum.COUSERID.getAlias(), originalCouserJsonArray);
                    if (!Objects.equals(LinkAddOperationFlagEnum.EDIT.getCode(), operationFlag)) {
                        contactValidateDataDTO.setIsNew(true);
                        contactValidateDataDTO.setDataId(null);
                        //web、移动端端新增联系人的时候标识为operationFlag为0, null的时候为编辑
                        if (Objects.equals(BasicConstant.ZERO, operationFlag) || Objects.equals(validateDataDTO.getIsImport(), BasicConstant.ONE)) {
                            //如果是0 代表客户新增联系人场景以及联合导入
                            contactValidateDataDTO.setUserId(validateDataDTO.getUserId());
                            contactValidateDataDTO.setCreatorId(Objects.nonNull(validateDataDTO.getUserId()) ? validateDataDTO.getUserId() : validateDataDTO.getCreatorId());
                            validateTeam(contactData, contactValidateDataDTO, validateDataDTO.getDistributorMark());
                        }else if (Objects.nonNull(contactDataId) && Objects.isNull(operationFlag)) {
                            //如果为null 代表有联系人数据但是不做任何处理.避免由于前端新增的时候操作标识也传了null,所以这时候再加个dataId用于区分
                            contactValidateDataDTO.setCreatorId(contactObj.getString(StringConstant.CREATOR_ID));
                            contactValidateDataDTO.setUserId(contactObj.getString(StringConstant.CREATOR_ID));
                        }else {
                            contactValidateDataDTO.setUserId(validateDataDTO.getUserId());
                            contactValidateDataDTO.setCreatorId(Objects.nonNull(validateDataDTO.getUserId()) ? validateDataDTO.getUserId() : validateDataDTO.getCreatorId());
                            validateTeam(contactData, contactValidateDataDTO, validateDataDTO.getDistributorMark());
                        }
                    }else {
                        contactValidateDataDTO.setUserId(validateDataDTO.getUserId());
                        contactValidateDataDTO.setCreatorId(contactObj.getString(StringConstant.CREATOR_ID));
                        contactValidateDataDTO.setIsNew(false);
                        validateTeam(contactData, contactValidateDataDTO, validateDataDTO.getDistributorMark());
                    }

                }
            } catch (XbbException e) {
                if (Objects.equals(e.getCode(), SystemErrorCodeEnum.API_ERROR_100034.getCode())) {
                    throw new XbbException(ContactErrorCodeEnum.API_ERROR_204008);
                } else {
                    throw e;
                }
            }
            // bug-id：38576 TODO
//            saasSaveHelp.beforeSave(contactValidateDataDTO);
            if (Objects.equals(contactValidateDataDTO.getImportDelContact(), 1)) {
                contactValidateDataDTO.setDataId(null);
            }
            contactPhoneList.addAll(phoneListFromFormData);

            if (contactDataId != null) {
                if (Objects.equals(operationFlag, LinkAddOperationFlagEnum.DEL.getCode())) {
                    ValidateDataDTO newDelContactDTO = new ValidateDataDTO();
                    BeanUtil.copyProperties(contactValidateDataDTO, newDelContactDTO);
                    needDelValidateDataDTO.add(newDelContactDTO);
                    continue;
                }
                // 没有更改的的联系人
                if (!Objects.equals(operationFlag, LinkAddOperationFlagEnum.EDIT.getCode())) {
                    continue;
                }
            }

            if (contactDataId != null) {
                ValidateDataDTO newUpdateContactDTO = new ValidateDataDTO();
                BeanUtil.copyProperties(contactValidateDataDTO, newUpdateContactDTO);
                needUpdateValidateDataDTO.add(newUpdateContactDTO);
            } else {
                ValidateDataDTO newAddContactDTO = new ValidateDataDTO();
                BeanUtil.copyProperties(contactValidateDataDTO, newAddContactDTO);
                needAddValidateDataDTO.add(newAddContactDTO);
            }
            newContactArr.add(contactData);
        }
        SaasNeedRedundantAttrPojo customerPojo = new SaasNeedRedundantAttrPojo();
        customerPojo.setNeedAddValidateDataDTO(needAddValidateDataDTO);
        customerPojo.setNeedDelValidateDataDTO(needDelValidateDataDTO);
        customerPojo.setNeedUpdateValidateDataDTO(needUpdateValidateDataDTO);
        validateDataDTO.setSaasNeedRedundantAttrPoJo(customerPojo);
    }

    /**
     * 校验团队并且往参数中封装团队信息
     *
     * @param json
     * @param validateDataDTO
     * @param distributorMark 经销商标识
     */
    private void validateTeam(JSONObject json, ValidateDataDTO validateDataDTO, Integer distributorMark) throws XbbException {
        if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())) {
            return;
        }
        //因为采购合同批量新建付款单的时候，validateDataDTO最外层也有采购合同的负责任人、协同人，所以需要把最外层的先移除掉
        validateDataDTO.setOwnerIds(null);
        validateDataDTO.setCoUserId(null);
        JSONArray teamMainPojoArray = json.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
        JSONArray teamCoPojoArray = json.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
        if (Objects.nonNull(teamMainPojoArray) && teamMainPojoArray.size() > BasicConstant.ZERO) {
            List<ReturnUserAndDepartmentPojo> ownerIds = teamMainPojoArray.toJavaList(ReturnUserAndDepartmentPojo.class);
            validateDataDTO.setOwnerIds(ownerIds);
        }
        if (Objects.nonNull(teamCoPojoArray) && teamCoPojoArray.size() > BasicConstant.ZERO) {
            List<ReturnUserAndDepartmentPojo> coUserIds = teamCoPojoArray.toJavaList(ReturnUserAndDepartmentPojo.class);
            validateDataDTO.setCoUserId(coUserIds);
        }
        try {
            teamUserHelp.beforeVerifyUserTeam(validateDataDTO);
            TeamAfterVerifyDTO teamAfterVerifyDTO = validateDataDTO.getSaasNeedRedundantAttrPoJo().getTeamAfterVerifyDTO();
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo = new SaasNeedRedundantAttrPojo();
            BeanUtil.copyProperties(validateDataDTO.getSaasNeedRedundantAttrPoJo(),saasNeedRedundantAttrPojo);
            saasNeedRedundantAttrPojo.setTeamAfterVerifyDTO(teamAfterVerifyDTO);
            validateDataDTO.setSaasNeedRedundantAttrPoJo(saasNeedRedundantAttrPojo);
            validateDataDTO.setTeamAfterVerifyDTO(teamAfterVerifyDTO);
        } catch (XbbException e) {
            throw new XbbException(e.getCode(), teamUserHelp.formatErrorMessage(e.getCode(), e.getMsg(), XbbRefTypeEnum.CONTACT));
        }
    }

    /**
     * 客户阶段关联客户状态：客户状态未设置值时，使用客户阶段设置时关联的客户状态
     *
     * @param data 数据
     * @param corpid 公司id
     * @param dataId 数据id
     * @param formId 表单id
     * @throws
     * @return
     * @author hongxiao
     * @date 2021-07-04 12:35
     * @since
     * @version
     */
    private void handleCustomerStageLinkCustomerType(JSONObject data, String corpid, Long dataId, Long formId) {
        try {
            if (Objects.nonNull(dataId) && dataId > 0L) {
                return;
            }
            if (!data.containsKey(CustomerManagementEnum.TYPE.getAttr())) {
                return;
            }
            if (!data.containsKey(CustomerManagementEnum.CUSTOMER_STAGE.getAttr())) {
                return;
            }
            // 客户状态
            String type = data.getString(CustomerManagementEnum.TYPE.getAttr());
            if (StringUtil.isNotEmpty(type)) {
                return;
            }
            // 客户阶段
            String stage = data.getString(CustomerManagementEnum.CUSTOMER_STAGE.getAttr());
            if (StringUtil.isEmpty(stage)) {
                return;
            }

            // 阶段关联的客户状态
            CustomerStageEntity customerStage = customerStageModel.getByCode(corpid, formId, stage);
            if (Objects.isNull(customerStage)) {
                return;
            }
            type = Objects.toString(customerStage.getBusinessRelatedStatus(), BasicConstant.ZERO.toString());
            // 非0为关联客户状态
            if (Objects.equals(1, customerStage.getOpenStatus()) && !Objects.equals(BasicConstant.ZERO.toString(), type)) {
                data.put(CustomerManagementEnum.TYPE.getAttr(), type);
            }
        } catch (Exception e) {

        }
    }
}
